package structures;

public class LinkedListTests
{
    public static class Node
    {
        int myData;
        Node myNext;
        
        Node(int data) 
        {
            myData = data;
            myNext = null;
        }
        
        public int getData()
        {
            return myData;
        }
        
        public Node getNext()
        {
            return myNext;
        }
        
        public void setNext(Node next)
        {
            myNext = next;
        }
            
    }
    
    public static void main(String[] args)
    {
        System.out.println("Lets create the linked list: ");
        if (args.length > 20) {
            System.err.println("Not valid for more than 20 entries");
        }
        
        Node headerNode= null;
        Node prev = null;
        for (String s : args) {
            Node node = new Node(Integer.parseInt(s));
            if (prev != null) {
                prev.setNext(node);
            }
            else {
                // to mark the first node to hold the reference
                headerNode = node;
            }
            prev = node;
        }
        
        // Print the list created.
        LinkedListTests.printList(headerNode);
        
        // Insert an element at first.
        headerNode = LinkedListTests.insertFirst(headerNode, 0);
        LinkedListTests.printList(headerNode);
        
        // Insert an element at last
        headerNode = LinkedListTests.insertLast(headerNode, 100);
        LinkedListTests.printList(headerNode);
        
        // Insert one element to null list.
        Node node = LinkedListTests.insertLast(null, 100);
        LinkedListTests.printList(node);
        
        // Delete a data item not present 
        headerNode = LinkedListTests.deleteNode(headerNode, 444);
        
        // Delete a valid item
        System.out.println("Deleting element with data 98");
        headerNode = LinkedListTests.deleteNode(headerNode, 98);
        LinkedListTests.printList(headerNode);
    }

    private static void printList(Node headerNode)
    {
        Node node = headerNode;
        if (headerNode == null) {
            System.out.println("List is empty");
            return;
        }
        
        StringBuilder sb = new StringBuilder();
        while(node != null) {
            sb.append(node.getData() + " ");
            node = node.getNext();
        }
        
        System.out.println(sb.toString());
    }
    
    private static Node insertFirst(Node headerNode, int num)
    {
        Node node = new Node(num);
        node.setNext(headerNode);
        
        return node;
    }
    
    private static Node insertLast(Node headerNode, int num)
    {
        if (headerNode == null) {
            headerNode = new Node(num);
            return headerNode; 
        }
        
        Node node = headerNode;
        while(node.getNext() != null) {
            node = node.getNext();
        }
        
        node.setNext(new Node(num));
        
        return headerNode;
    }
    
    private static Node deleteNode(Node headerNode, int num)
    {
        if (headerNode == null) {
            System.out.println("Cannot delete data from empty list");
            return null;
        }
        
        Node prev = null;
        Node node = headerNode;
        while(node != null && node.getData() != num) {
            prev = node;
            node = node.getNext();
        }
        
        if (node == null) {
            System.out.println("Did not find element with data " + num);
            return headerNode;
        }
        else {
            prev.setNext(node.getNext());
            return headerNode;
        }   
    }
}
